package net.ericaro.neogrex;

import java.awt.BorderLayout;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import net.ericaro.parser.ParseException;
import net.ericaro.parser.RegExpParser;
import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse.Mode;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
/* contains a simple implementatio of a graph, used to display regexps
 * 
 */
public class GrexUtil {
	public static class T {
		private static int count = 0;
		String name;
		int id;

		public T(T t) {
			this(t.name);
		}

		public T(String name) {
			super();
			this.name = name;
			this.id = ++count;
		}

		public String toString() {
			return name + "[" + id + "]";
		}
	}

	public static class S {
		private static int count = 0;
		int id;
		String name;

		public S(S s) {
			this(s.name);
		}

		public S(String name) {
			super();
			this.name = name;
			this.id = ++count;
		}

		@Override
		public String toString() {
			return name + "[" + id + "]";
		}

	}

	public static class GrexST extends Grex<S, T> {

		public GrexST() {
			super();
		}

		public GrexST(T t, S src, S target) {
			super(t, src, target);
		}

		@Override
		protected S newState() {
			return new S("S");
		}

		@Override
		protected T cloneTransition(T t) {
			return new T(t);
		}

		@Override
		protected Grex<S, T> newInstance() {
			return new GrexST();
		}
	}

	public static GrexST term(String name) {
		S s1 = new S("1");
		S s2 = new S("2");
		T ta = new T(name);

		GrexST g1 = new GrexST(ta, s1, s2);
		return g1;
	}

	
	/**
	 * @param exp
	 */
	public static void check(String exp) {
		
		try {
		disp(exp,true);
		} catch (ParseException e) {
			assert false: "exception during the grex builbing "+e;
		}
		assert JOptionPane.OK_OPTION ==  JOptionPane.showConfirmDialog(null, "is it ok ?"): " fail to valid the regexp -> graph "+exp;
		
	}
	
	public static GrexST grex(String exp) throws ParseException {
		return RegExpParser.parse(exp, new RegExpGraphBuilder<GrexST, S, T>() {
			public GrexST terminal(String name) {
				return term(name);
			}
		});
	}

	public static void disp(String exp, boolean modal) throws ParseException {
		JDialog jf = new JDialog();
		jf.setModal(modal);
		//Layout<V, E> layout = new FRLayout<V, E>(g);
		final GrexST grex = grex(exp);
		Layout<S, T> layout = new ISOMLayout<S, T>(grex.g);

		//Layout<Integer, String> layout = new CircleLayout(g);
		VisualizationViewer<S, T> vv = new VisualizationViewer<S, T>(layout);
		// Show vertex and edge labels
		vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller() {

			@Override
			public String transform(Object v) {
				boolean in = grex.in == v;
				boolean out = grex.outs.contains(v);
				
				if (in && out)
					return "IN/OUT";
				else if (out)
					return "OUT";
				else if (in)
					return "IN";
				else
					return "";
			}
			
		});
		vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());
		// Create a graph mouse and add it to the visualization component
		DefaultModalGraphMouse gm = new DefaultModalGraphMouse();
		gm.setMode(Mode.PICKING);
		vv.setGraphMouse(gm);

		jf.getContentPane().add(new GraphZoomScrollPane(vv), BorderLayout.CENTER);
		jf.getContentPane().add(new JLabel("<html><b>"+exp+"</b>"), BorderLayout.NORTH);
		

		jf.setBounds(100, 100, 800, 600);
		jf.setVisible(true);
	}
	public static <S, T> void disp(Grex<S, T> g, boolean modal) {
		System.out.println(g.outs);
		disp(g.g, modal);

	}

	public static <V, E> void disp(Graph<V, E> g, boolean modal) {

		JDialog jf = new JDialog();
		jf.setModal(modal);
		//Layout<V, E> layout = new FRLayout<V, E>(g);
		Layout<V, E> layout = new ISOMLayout<V, E>(g);

		//Layout<Integer, String> layout = new CircleLayout(g);
		VisualizationViewer<V, E> vv = new VisualizationViewer<V, E>(layout);
		// Show vertex and edge labels
		vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
		vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());
		// Create a graph mouse and add it to the visualization component
		DefaultModalGraphMouse gm = new DefaultModalGraphMouse();
		gm.setMode(Mode.PICKING);
		vv.setGraphMouse(gm);

		jf.getContentPane().add(new GraphZoomScrollPane(vv));

		jf.setBounds(100, 100, 800, 600);
		jf.setVisible(true);
	}
}
